package com.seeyon.apps.commonExt.util;

import com.seeyon.cap4.form.api.FormApi4Cap4;
import com.seeyon.cap4.form.bean.*;
import com.seeyon.cap4.form.exception.FormException;
import com.seeyon.cap4.form.modules.engin.base.formData.CAP4SessionFormDataManager;
import com.seeyon.cap4.form.service.CAP4FormManager;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.v3x.services.form.FormFactory;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapUtil;

import org.apache.commons.logging.LogFactory;

import java.util.*;

/**
 * 用于存储到底表中--也可以封装成Http接口
 *
 * @author Administrator
 * @author 2020年5月22日
 */
public class SaveToFlowUtilExt {

    private static org.apache.commons.logging.Log logger = LogFactory.getLog(SaveToFlowUtilExt.class);

    private static FormBean form;
    private static FormFactory formFactory;
    private static CAP4FormManager cap4FormManager = (CAP4FormManager) AppContext.getBean("cap4FormManager");


    public static void saveOrUpdateFormData(FormDataMasterBean formDataMasterBean, Map<String, Object> formParams) {
        saveOrUpdateFormData(formDataMasterBean, formParams, true);
    }



    public static void saveOrUpdateFormData(FormDataMasterBean formDataMasterBean, Map<String, Object> formParams, boolean fillNull) {
        try {
            Map<String, Object> masterParams = new HashMap<>();
            Map<String, Object> subParams = new HashMap<>();
            for (Map.Entry<String, Object> entry : formParams.entrySet()) {
                if (entry.getValue() instanceof Collection) {
                    subParams.put(entry.getKey(), entry.getValue());
                }else {
                    masterParams.put(entry.getKey(), entry.getValue());
                }
            }

            // 主表
            for (Map.Entry<String, Object> materEntry : masterParams.entrySet()) {
                FormFieldBean fieldBean = formDataMasterBean.getFormTable().getFieldBeanByDisplay(materEntry.getKey());
                if (null == fieldBean) {
                    continue;
                }
                if (!fillNull && null == materEntry.getValue()) {
                    continue;
                }
                formDataMasterBean.addFieldValue(fieldBean.getName(), materEntry.getValue());
            }
            Set<String> clearDtlSet = MapUtil.get(subParams, "clearDtl", new TypeReference<Set<String>>() {
            }, new HashSet<>());
            Long formId = formDataMasterBean.getFormTable().getFormId();
            FormBean formBean = cap4FormManager.getForm(formId, true);

            // 明细
            for (Map.Entry<String, Object> subEntry : subParams.entrySet()) {
                FormTableBean tableBean = formBean.getSubTableBean().stream()
                        .filter(item -> item.getDisplay().equals(subEntry.getKey()))
                        .findFirst()
                        .orElse(null);
                if (null == tableBean) {
                    continue;
                }
                List<FormDataSubBean> subDatas = formDataMasterBean.getSubData(tableBean.getTableName());
                if (null == subDatas) {
                    subDatas = new ArrayList<>();
                }
                if (!subDatas.isEmpty()){
                    if (clearDtlSet.contains(tableBean.getDisplay())) {
                        subDatas.clear();
                    }
                }
                List<Map<String,Object>> dtlDatas = (List<Map<String, Object>>) subEntry.getValue();
                for (Map<String, Object> dtlData : dtlDatas) {
                    Long subId = MapUtil.getLong(dtlData, "id");
                    if (null == subId) {
                        FormDataSubBean formDataSubBean = new FormDataSubBean(tableBean, formDataMasterBean, new boolean[]{fillNull});
                        formDataSubBean.setDb(true);
                        combineSub(fillNull, dtlData, formDataSubBean, subDatas);
                        continue;
                    }
                    FormDataSubBean formDataSubBean = subDatas.stream().filter(item -> item.getId().equals(subId)).findFirst().orElse(null);
                    if (null == formDataSubBean) {
                        formDataSubBean = new FormDataSubBean(tableBean, formDataMasterBean, new boolean[]{fillNull});
                        formDataSubBean.setId(subId);
                        formDataSubBean.setDb(true);
                        combineSub(fillNull, dtlData, formDataSubBean, subDatas);
                        continue;
                    }
                    combineSub(fillNull, dtlData, formDataSubBean, null);
                }

                formDataMasterBean.setSubData(tableBean.getTableName(), subDatas);
            }
            FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
            formApi4Cap4.saveOrUpdateFormData(formDataMasterBean, formBean.getId(), true);
            CAP4SessionFormDataManager cap4SessionFormDataManager = (CAP4SessionFormDataManager) AppContext.getBean("cap4SessionFormDataManager");
            cap4SessionFormDataManager.put2Cache(formDataMasterBean, AppContext.currentUserId());
            
        } catch (Exception e) {
            throw new FormException(e.getMessage());
        }
    }


    private static int getIntType(String type) {
        int intType = 0;
        type = type.toUpperCase();
        if (type.equals("VARCHAR")) {
            intType = 0;
        }
        if (type.equals("LONGTEXT")) {
            intType = 1;
        }
        if (type.equals("DATETIME")) {
            intType = 2;
        }
        if (type.equals("TIMESTAMP")) {
            intType = 3;
        }

        if (type.equals("DECIMAL")) {
            intType = 4;
        }
        if (type.equals("HANDWRITE")) {
            intType = 5;
        }
        return intType;
    }

    private static void combineSub(boolean fillNull, Map<String, Object> dtlData, FormDataSubBean formDataSubBean, List<FormDataSubBean> subDatas) {
        for (Map.Entry<String, Object> subFieldDataEntry : dtlData.entrySet()) {
            FormFieldBean subFormFieldBean = formDataSubBean.getFormTable().getFieldBeanByDisplay(subFieldDataEntry.getKey());
            if (null == subFormFieldBean) {
                continue;
            }
            if (!fillNull && null == subFieldDataEntry.getValue()) {
                continue;
            }
            formDataSubBean.addFieldValue(subFormFieldBean.getName(), subFieldDataEntry.getValue());
        }
        if (null == subDatas) {
            return;
        }
        subDatas.add(formDataSubBean);
    }

}
